package org.xiaov.codeautocreator.util;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.WordUtils;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.xiaov.codeautocreator.entity.ColumnEntity;
import org.xiaov.codeautocreator.entity.TableEntity;
import org.xiaov.codeautocreator.exception.CodeAutoBizException;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * <p>
 * 描述：自动生成工具类
 * </p>
 *
 * @author xiaovcloud
 * @since 2021/9/13 18:00
 */
@Slf4j
public class AutoCodeUtils {

	private static Properties props;

	static {
		loadProps();
	}

	public static List<String> getTemplates() {
		List<String> templates = new ArrayList<String>();
		templates.add("template/Entity.java.vm");
		templates.add("template/Dao.xml.vm");

		templates.add("template/menu.sql.vm");

		templates.add("template/Service.java.vm");
		templates.add("template/ServiceImpl.java.vm");
		templates.add("template/Controller.java.vm");
		templates.add("template/Dao.java.vm");

		templates.add("template/index.vue.vm");
		templates.add("template/add-or-update.vue.vm");

		return templates;
	}


	/**
	 * 自动生成代码
	 *
	 * @param table
	 * @param columns
	 * @param zip
	 */
	public static void autocode(TableEntity table, List<ColumnEntity> columns, ZipOutputStream zip) {
		//配置信息


		//设置velocity资源加载器
		Properties prop = new Properties();
		prop.put("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
		Velocity.init(prop);
//		String mainPath = config.getString("mainPath");
//		mainPath = StringUtils.isBlank(mainPath) ? "io.renren" : mainPath;
		//封装模板数据
		Map<String, Object> map = new HashMap<>();
		map.put("tableName", table.getTableName());
		map.put("comments", table.getComments());
		map.put("pk", table.getPk());
		map.put("className", table.getClassName());
		map.put("classname", table.getClassname());
		map.put("pathName", table.getClassname().toLowerCase());
		map.put("columns", table.getColumns());
//		map.put("hasBigDecimal", hasBigDecimal);
//		map.put("hasList", hasList);
//		map.put("mainPath", mainPath);
//		map.put("package", config.getString("package"));
//		map.put("moduleName", config.getString("moduleName"));
//		map.put("author", config.getString("author"));
//		map.put("email", config.getString("email"));
//		map.put("datetime", DateUtils.format(new Date(), DateUtils.DATE_TIME_PATTERN));
		VelocityContext context = new VelocityContext(map);

		//获取模板列表
		List<String> templates = getTemplates();
		for (String template : templates) {
			//渲染模板
			StringWriter sw = new StringWriter();
			Template tpl = Velocity.getTemplate(template, "UTF-8");
			tpl.merge(context, sw);

//			try {
//				//添加到zip
////				zip.putNextEntry(new ZipEntry(getFileName(template, table.getClassName(), config.getString("package"), config.getString("moduleName"))));
////				IOUtils.write(sw.toString(), zip, "UTF-8");
////				IOUtils.closeQuietly(sw);
////				zip.closeEntry();
//			} catch (IOException e) {
//				throw new CodeAutoBizException("渲染模板失败，表名：" + table.getTableName(), e);
//			}
		}
	}

	/**
	 * 列名转换成Java属性名
	 */
	public static String columnToJava(String columnName) {
		return WordUtils.capitalizeFully(columnName, new char[]{'_'}).replace("_", "");
	}

	/**
	 * 表名转换成Java类名
	 */
	public static String tableToJava(String tableName, String[] tablePrefixArray) {
		if (null != tablePrefixArray && tablePrefixArray.length > 0) {
			for (String tablePrefix : tablePrefixArray) {
				if (tableName.startsWith(tablePrefix)){
					tableName = tableName.replaceFirst(tablePrefix, "");
				}
			}
		}
		return columnToJava(tableName);
	}

	/**
	 * 读取配置文件
	 */
	synchronized static private void loadProps() {
		log.info("开始加载properties文件内容.......");
		props = new Properties();
		InputStream in = null;
		try {
			in = AutoCodeUtils.class.getClassLoader().getResourceAsStream("autocode.properties");
			props.load(in);
		} catch (FileNotFoundException e) {
			log.error("autocode.properties文件未找到");
		} catch (IOException e) {
			log.error("出现IOException");
		} finally {
			try {
				if (null != in) {
					in.close();
				}
			} catch (IOException e) {
				log.error("autocode.properties文件流关闭出现异常");
			}
		}
		log.info("加载properties文件内容完成...........");
		log.info("properties文件内容：" + props);
	}

	public static String getProperty(String key){
		if(null == props) {
			loadProps();
		}
		return props.getProperty(key);
	}

	public static String getProperty(String key, String defaultValue) {
		if(null == props) {
			loadProps();
		}
		return props.getProperty(key, defaultValue);
	}
}
